﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSConsoleTest
{
    class TestIndexerGeneric : BaseConsoleTest
    {
        public void printDescription()
        {
            Console.WriteLine("--- Generic Indexser, Iterator ---");
        }

        public void doTest()
        {
            CustomArray<int> customArray = new CustomArray<int>(10);

            for (int index = 0; index < 10; index++)
            {
                customArray[index] = (index + 1) * 100;
            }

            foreach (int value in customArray)
            {
                Console.Write("{0} ", value);
            }
            Console.WriteLine();
        }
    }

    
    class CustomArray<T> : IEnumerable<T>, IEnumerator<T>
    {
        private T[] mData;
        private int mCurrentIndex;

        public CustomArray(int aMaxSize)
        {
            mData = new T[aMaxSize];
            mCurrentIndex = -1;
        }

        public T this[int aIndex]
        {
            get
            {
                if(aIndex < 0 || aIndex > mCurrentIndex)
                {
                    throw new IndexOutOfRangeException("Index : "+aIndex+" is invalid.");
                }

                return mData[aIndex];
            }

            set
            {
                if (aIndex < 0 || aIndex > mData.Length - 1)
                {
                    throw new IndexOutOfRangeException("Index : " + aIndex + " is invalid.");
                }

                mData[aIndex] = value;
            }
        }

        public IEnumerator GetEnumerator()
        {
            int maxLength = mData.Length;
            for (int i = 0; i < maxLength; i++)
            {
                yield return (mData[i]);
            }
        }

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            int maxLength = mData.Length;
            for (int i = 0; i < maxLength; i++)
            {
                yield return (mData[i]);
            }
        }

        object IEnumerator.Current
        {
            get
            {
                if (mCurrentIndex < 0)
                {
                    throw new IndexOutOfRangeException("Index : " + mCurrentIndex + " is invalid.");
                }

                return mData[mCurrentIndex];
            }
        }

        public T Current
        {
            get
            {
                if (mCurrentIndex < 0)
                {
                    throw new IndexOutOfRangeException("Index : " + mCurrentIndex + " is invalid.");
                }

                return mData[mCurrentIndex];
            }
        }

        public bool MoveNext()
        {
            if (mCurrentIndex + 1 == mData.Length)
            {
                return false;
            }

            mCurrentIndex++;
            return true;
        }

        public void Reset()
        {
            mCurrentIndex = -1;
        }

        public void Dispose()
        {
            
        }
        
    }
}
